package scigest.configuration;

import java.io.IOException;

import org.apache.commons.configuration.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.martiansoftware.jsap.FlaggedOption;
import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPException;
import com.martiansoftware.jsap.JSAPResult;
import com.martiansoftware.jsap.Switch;
import com.martiansoftware.jsap.UnflaggedOption;

/**
 * 
 * This command class provides the following sub-commands to interact with with the scigest
 * configuration management.
 * 
 * <ul>
 * 
 * <li> <code>set key value</code>: set property locally
 * <li> <code>get key</code>: retrieve property, it can be partial and we will do partial matching
 * <li> <code>list</code>: show all properties in effect 
 * <li> <code>restore</code>: restore all properties to its default value
 * 
 * </ul>
 * 
 * @author Feiyi Wang
 *
 */
public class ScigestCmd {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws ConfigurationException 
	 * @throws JSAPException 
	 */

	public static final String CMD_LIST 	= "list";
	public static final String CMD_SET  	= "set";
	public static final String CMD_GET  	= "get";
	public static final String CMD_RESTORE 	= "restore";

	private static final Logger logger = LoggerFactory.getLogger(ScigestCmd.class);
	private static ScigestConfiguration sc;
	
	public static void main(String[] args) throws ConfigurationException, IOException, JSAPException {
		
		sc = new ScigestConfiguration();
		JSAP jsap = new JSAP();

		CmdParser cmdParser = new CmdParser();
		UnflaggedOption command = new UnflaggedOption("command")
											.setStringParser(cmdParser)
											.setRequired(true);
		
		jsap.registerParameter(command);
		
		Switch local = new Switch("local")
								.setShortFlag('l')
								.setLongFlag("local");
		
		jsap.registerParameter(local);
		
		UnflaggedOption key = new UnflaggedOption("key")
											.setStringParser(JSAP.STRING_PARSER)
											.setRequired(false)
											.setGreedy(false);
		
		jsap.registerParameter(key);

		UnflaggedOption val = new UnflaggedOption("value")
											.setStringParser(JSAP.STRING_PARSER)
											.setRequired(false)
											.setGreedy(false);
		
		jsap.registerParameter(val);
		
		JSAPResult config = jsap.parse(args);
				
		usage(jsap, config);
		
		String subCmd = config.getString("command");

		if (subCmd.equals(CMD_GET)) {
			processKey(config.getString("key"));
			
		} else if (subCmd.equals(CMD_LIST)) {
			if (config.getBoolean("local"))
				processListLocal();
			else 
				processList();
		} else if (subCmd.equals(CMD_SET)) {
			String propKey = config.getString("key");
			String propVal = config.getString("value");
			if ( ( propKey==null) || (propVal == null)) {
				logger.error("either property key or proerty value is missing!");
				System.exit(1);
			}
			processSet(propKey, propVal);
		} else if (subCmd.equals(CMD_RESTORE)) {
			processRestore();
		} 
		
	}

	private static void processKey(String key) {
		String[] keyList = sc.getKeys();
		
		for (int i = 0; i < keyList.length; i++) {
			if (keyList[i].startsWith(key)) {
				System.out.printf("%s %s\n", keyList[i], sc.getString(keyList[i]));
			}
		}
	}
	
	private static void processList() {
		String[] keyList = sc.getKeys();
		
		System.out.println("");		
		for (int i = 0; i < keyList.length; i++) {
				System.out.printf("%s=%s\n", keyList[i], sc.getString(keyList[i]));
		}
		System.out.println("");		

	}

	private static void processListLocal() {
		String[] keyList = sc.getLocalKeys();
		
		System.out.println("");		
		for (int i = 0; i < keyList.length; i++ ) {
			System.out.printf("%s=%s\n", keyList[i], sc.getLocalVal(keyList[i]));
		}
		System.out.println("");		

	}

	
	private static void processSet(String key, String val) throws ConfigurationException {
		sc.setString(key, val);
	}
	
	
	private static void processRestore() throws ConfigurationException {
		sc.reset();
		System.out.println("\nAll local changes are reset!\n");
		
	}
	
	private static void usage(JSAP jsap, JSAPResult config) {
		if (!config.success()) {
			System.err.println();
			System.err.println("Usage: java "
						+ ScigestCmd.class.getName());
			System.err.println("              "
				+ jsap.getUsage());
			System.err.println();
			System.exit(1);
		}
	}

}
